# encoding: UTF-8

'''
CTA模块相关的GUI控制组件
'''

from PyQt4 import  QtGui, QtCore
from engine import *
from basicWidget import BasicCell


########################################################################
class CtaValueMonitor(QtGui.QTableWidget):
    """参数监控"""

    # ----------------------------------------------------------------------
    def __init__(self, parent=None):
        """Constructor"""
        super(CtaValueMonitor, self).__init__(parent)

        self.keyCellDict = {}
        self.data = None
        self.inited = False

        self.initUi()

    # ----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setRowCount(1)
        self.verticalHeader().setVisible(False)
        self.setEditTriggers(self.NoEditTriggers)

        self.setMaximumHeight(self.sizeHint().height())

    # ----------------------------------------------------------------------
    def updateData(self, data):
        """更新数据"""
        if not self.inited:
            self.setColumnCount(len(data))
            self.setHorizontalHeaderLabels(data.keys())

            col = 0
            for k, v in data.items():
                cell = QtGui.QTableWidgetItem(unicode(v))
                self.keyCellDict[k] = cell
                self.setItem(0, col, cell)
                col += 1

            self.inited = True
        else:
            for k, v in data.items():
                cell = self.keyCellDict[k]
                cell.setText(unicode(v))


########################################################################
class PositionMonitor(QtGui.QTableWidget):
    """参数监控"""

    # ----------------------------------------------------------------------
    def __init__(self, parent=None):
        """Constructor"""
        super(PositionMonitor, self).__init__(parent)

        self.keyCellDict = {}
        self.data = None
        self.inited = False

        self.initUi()

    # ----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""

        self.verticalHeader().setVisible(False)
        self.setEditTriggers(self.NoEditTriggers)
        maxHeight = 2000
        self.setMaximumHeight(maxHeight)
        self.setColumnCount(2)
        self.setHorizontalHeaderLabels([u'股票代码', u'持仓'])
        self.setRowCount(10)
        for i in range(0, 10):
            d = {}
            cell1 = QtGui.QTableWidgetItem()
            cell2 = QtGui.QTableWidgetItem()
            self.setItem(i, 0, cell1)
            self.setItem(i, 1, cell2)
            d[0] = cell1
            d[1] = cell2
            self.keyCellDict[i] = d

    # ----------------------------------------------------------------------
    def updateData(self, data):
        """更新数据"""
        stocks = data.keys()
        for i, cells in self.keyCellDict.items():
            if i < len(stocks):
                stock = stocks[i]
                cells[0].setText(unicode(stock))
                cells[1].setText(unicode(data[stock]))
            else:
                cells[0].setText(u'')
                cells[1].setText(u'')


########################################################################
class CtaStrategyManager(QtGui.QGroupBox):
    """策略管理组件"""
    signal = QtCore.pyqtSignal()
    posSignal = QtCore.pyqtSignal(dict)

    # ----------------------------------------------------------------------
    def __init__(self, mainEngine, name, parent=None):
        """Constructor"""
        super(CtaStrategyManager, self).__init__(parent)

        self.mainEngine = mainEngine
        self.name = name

        self.initUi()
        self.updateMonitor()
        self.registerEvent()

    # ----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setTitle(self.name)

        self.paramMonitor = CtaValueMonitor(self)
        self.varMonitor = CtaValueMonitor(self)
        self.posMonitor = PositionMonitor(self)

        maxHeight = 60
        self.paramMonitor.setMaximumHeight(maxHeight)
        self.varMonitor.setMaximumHeight(maxHeight)

        buttonInit = QtGui.QPushButton(u'初始化')
        buttonStart = QtGui.QPushButton(u'启动')
        buttonStop = QtGui.QPushButton(u'停止')
        buttonResult = QtGui.QPushButton(u'查看收益')
        buttonInit.clicked.connect(self.init)
        buttonStart.clicked.connect(self.start)
        buttonStop.clicked.connect(self.stop)
        buttonResult.clicked.connect(self.result)

        hbox1 = QtGui.QHBoxLayout()
        hbox1.addWidget(buttonInit)
        hbox1.addWidget(buttonStart)
        hbox1.addWidget(buttonStop)
        hbox1.addWidget(buttonResult)
        hbox1.addStretch()

        hbox2 = QtGui.QHBoxLayout()
        hbox2.addWidget(self.paramMonitor)

        hbox3 = QtGui.QHBoxLayout()
        hbox3.addWidget(self.varMonitor)

        hbox4 = QtGui.QHBoxLayout()
        hbox4.addWidget(self.posMonitor)

        vbox = QtGui.QVBoxLayout()
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)

        self.setLayout(vbox)

    # ----------------------------------------------------------------------
    def updateMonitor(self):
        """显示策略最新状态"""
        paramDict = self.mainEngine.getStrategyParam(self.name)
        if paramDict:
            self.paramMonitor.updateData(paramDict)

        varDict = self.mainEngine.getStrategyVar(self.name)
        if varDict:
            self.varMonitor.updateData(varDict)


            # ----------------------------------------------------------------------

    def registerEvent(self):
        """注册事件监听"""
        self.signal.connect(self.updateMonitor)
        self.mainEngine.getStrategyEvent().subscribe(self.signal.emit)
        self.posSignal.connect(self.posMonitor.updateData)
        self.mainEngine.getPositionsEvent().subscribe(self.posSignal.emit)

    # ----------------------------------------------------------------------
    def init(self):
        """初始化策略"""
        self.mainEngine.initStrategy(self.name)

    # ----------------------------------------------------------------------
    def start(self):
        """启动策略"""
        self.startWorker = startStrageyWorker(self.mainEngine, self.name, self)
        # self.startWorker.logSignal.connect(self.updateMonitor)
        # self.startWorker.posSignal.connect(self.posMonitor.updateData)
        self.startWorker.start()

    # ----------------------------------------------------------------------
    def stop(self):
        """停止策略"""
        self.mainEngine.stopStrategy(self.name)

    def result(self):
        """查看收益"""
        self.mainEngine.getStrategyResult(self.name)


########################################################################
class CtaEngineManager(QtGui.QWidget):
    """CTA引擎管理组件"""
    signal = QtCore.pyqtSignal(dict)

    # ----------------------------------------------------------------------
    def __init__(self, mainEngine, parent=None):
        """Constructor"""
        super(CtaEngineManager, self).__init__(parent)

        self.mainEngine = mainEngine

        self.strategyLoaded = False

        self.initUi()
        self.registerEvent()

        # 记录日志
        self.mainEngine.writeCtaLog(u'策略引擎启动成功')

        # ----------------------------------------------------------------------

    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(u'股票策略')

        # 按钮
        loadButton = QtGui.QPushButton(u'加载策略')
        initAllButton = QtGui.QPushButton(u'全部初始化')
        startAllButton = QtGui.QPushButton(u'全部启动')
        stopAllButton = QtGui.QPushButton(u'全部停止')

        loadButton.clicked.connect(self.load)
        initAllButton.clicked.connect(self.initAll)
        startAllButton.clicked.connect(self.startAll)
        stopAllButton.clicked.connect(self.stopAll)

        # 滚动区域，放置所有的CtaStrategyManager
        self.scrollArea = QtGui.QScrollArea()
        self.scrollArea.setWidgetResizable(True)

        # CTA组件的日志监控
        self.logMonitor = QtGui.QTextEdit()
        self.logMonitor.setReadOnly(True)
        self.logMonitor.setMaximumHeight(200)

        # 设置布局
        hbox2 = QtGui.QHBoxLayout()
        hbox2.addWidget(loadButton)
        hbox2.addWidget(initAllButton)
        hbox2.addWidget(startAllButton)
        hbox2.addWidget(stopAllButton)
        hbox2.addStretch()

        vbox = QtGui.QVBoxLayout()
        vbox.addLayout(hbox2)
        vbox.addWidget(self.scrollArea)
        vbox.addWidget(self.logMonitor)
        self.setLayout(vbox)

    # ----------------------------------------------------------------------
    def initStrategyManager(self):
        """初始化策略管理组件界面"""
        w = QtGui.QWidget()
        vbox = QtGui.QVBoxLayout()

        for name in self.mainEngine.strategyDict.keys():
            strategyManager = CtaStrategyManager(self.mainEngine, name)
            vbox.addWidget(strategyManager)

        vbox.addStretch()

        w.setLayout(vbox)
        self.scrollArea.setWidget(w)

        # ----------------------------------------------------------------------

    def initAll(self):
        """全部初始化"""
        for name in self.mainEngine.strategyDict.keys():
            self.mainEngine.initStrategy(name)

            # ----------------------------------------------------------------------

    def startAll(self):
        """全部启动"""
        for name in self.mainEngine.strategyDict.keys():
            self.mainEngine.startStrategy(name)

    # ----------------------------------------------------------------------
    def stopAll(self):
        """全部停止"""
        for name in self.mainEngine.strategyDict.keys():
            self.mainEngine.stopStrategy(name)

    # ----------------------------------------------------------------------
    def load(self):
        """加载策略"""
        if not self.strategyLoaded:
            self.mainEngine.loadSetting()
            self.initStrategyManager()
            self.strategyLoaded = True
            self.mainEngine.writeCtaLog(u'策略加载成功')

    # ----------------------------------------------------------------------
    def updateCtaLog(self, data):
        """更新CTA相关日志"""
        log = data['data']
        content = '\t'.join([log.logTime, log.logContent])
        self.logMonitor.append(content)

    # ----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signal.connect(self.updateCtaLog)
        self.mainEngine.getLogEvent().subscribe(self.signal.emit)


class startStrageyWorker(QtCore.QThread):
    logSignal = QtCore.pyqtSignal(dict)
    posSignal = QtCore.pyqtSignal(dict)

    def __init__(self, mainEngine, strageyName, parent=None):
        QtCore.QThread.__init__(self, parent)
        self.mainEngine = mainEngine
        self.strageyName = strageyName

    def run(self):
        self.mainEngine.startStrategy(self.strageyName)
        self.mainEngine.getLogEvent().subscribe(self.logSignal.emit)
        self.mainEngine.getPositionsEvent().subscribe(self.posSignal.emit)


if __name__ == '__main__':
    import sys

    reload(sys)

    app = QtGui.QApplication(sys.argv)
    mainEngine = Engine()
    cta = CtaEngineManager(mainEngine)
    cta.showMaximized()

    sys.exit(app.exec_())











